{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "e5929f99",
   "metadata": {},
   "source": [
    "| [03_data_science/08_Pandas数据操作.ipynb](https://github.com/shibing624/python-tutorial/blob/master/03_data_science/08_Pandas数据操作.ipynb)  | Pandas操作  |[Open In Colab](https://colab.research.google.com/github/shibing624/python-tutorial/blob/master/03_data_science/08_Pandas数据操作.ipynb) |\n",
    "\n",
    "# 3. Pandas数据操作"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4fd9c2a5",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "在第一部分的基础上，数据会有更多种操作方式：\n",
    "\n",
    "* 通过列名、行index来取数据，结合ix、iloc灵活的获取数据的一个子集（第一部分已经介绍）\n",
    "* 按记录拼接（就像Union All）或者关联（join）\n",
    "* 方便的自定义函数映射\n",
    "* 排序\n",
    "* 缺失值处理\n",
    "* 与Excel一样灵活的数据透视表（在第四部分更详细介绍）"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3c297ec7",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "### 3.1 数据整合：方便灵活"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1502ccdd",
   "metadata": {},
   "source": [
    "### 3.1.1 横向拼接：直接DataFrame"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "c4b158bd",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>C1</th>\n",
       "      <th>C2</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0.838146</td>\n",
       "      <td>0.470503</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>0.107491</td>\n",
       "      <td>0.243259</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>0.604792</td>\n",
       "      <td>0.652182</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "         C1        C2\n",
       "0  0.838146  0.470503\n",
       "1  0.107491  0.243259\n",
       "2  0.604792  0.652182"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "pd.DataFrame([np.random.rand(2), np.random.rand(2), np.random.rand(2)], columns=['C1', 'C2'])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e4299b6b",
   "metadata": {},
   "source": [
    "### 3.1.2 横向拼接：Concatenate"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "e0f56e13",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>name</th>\n",
       "      <th>job</th>\n",
       "      <th>sal</th>\n",
       "      <th>report</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>Wang</td>\n",
       "      <td>VP</td>\n",
       "      <td>50000.0</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>Zhang</td>\n",
       "      <td>Manager</td>\n",
       "      <td>NaN</td>\n",
       "      <td>VP</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>Li</td>\n",
       "      <td>NaN</td>\n",
       "      <td>5000.0</td>\n",
       "      <td>Manager</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>Wang</td>\n",
       "      <td>VP</td>\n",
       "      <td>50000.0</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>Zhang</td>\n",
       "      <td>Manager</td>\n",
       "      <td>NaN</td>\n",
       "      <td>VP</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>Li</td>\n",
       "      <td>NaN</td>\n",
       "      <td>5000.0</td>\n",
       "      <td>Manager</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>Wang</td>\n",
       "      <td>VP</td>\n",
       "      <td>50000.0</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>Zhang</td>\n",
       "      <td>Manager</td>\n",
       "      <td>NaN</td>\n",
       "      <td>VP</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>Li</td>\n",
       "      <td>NaN</td>\n",
       "      <td>5000.0</td>\n",
       "      <td>Manager</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "    name      job      sal   report\n",
       "0   Wang       VP  50000.0      NaN\n",
       "1  Zhang  Manager      NaN       VP\n",
       "2     Li      NaN   5000.0  Manager\n",
       "0   Wang       VP  50000.0      NaN\n",
       "1  Zhang  Manager      NaN       VP\n",
       "2     Li      NaN   5000.0  Manager\n",
       "0   Wang       VP  50000.0      NaN\n",
       "1  Zhang  Manager      NaN       VP\n",
       "2     Li      NaN   5000.0  Manager"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import json\n",
    "json_data = [{'name': 'Wang', 'sal': 50000, 'job': 'VP'},\n",
    "             {'name': 'Zhang', 'job': 'Manager', 'report': 'VP'},\n",
    "             {'name': 'Li', 'sal': 5000, 'report': 'Manager'}]\n",
    "data_employee = pd.read_json(json.dumps(json_data))\n",
    "data_employee_ri = data_employee.reindex(columns=['name', 'job', 'sal', 'report'])\n",
    "\n",
    "pd.concat([data_employee_ri, data_employee_ri, data_employee_ri])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "25779a66",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>name</th>\n",
       "      <th>job</th>\n",
       "      <th>sal</th>\n",
       "      <th>report</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>Wang</td>\n",
       "      <td>VP</td>\n",
       "      <td>50000.0</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>Zhang</td>\n",
       "      <td>Manager</td>\n",
       "      <td>NaN</td>\n",
       "      <td>VP</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>Li</td>\n",
       "      <td>NaN</td>\n",
       "      <td>5000.0</td>\n",
       "      <td>Manager</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>Wang</td>\n",
       "      <td>VP</td>\n",
       "      <td>50000.0</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>Zhang</td>\n",
       "      <td>Manager</td>\n",
       "      <td>NaN</td>\n",
       "      <td>VP</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>Li</td>\n",
       "      <td>NaN</td>\n",
       "      <td>5000.0</td>\n",
       "      <td>Manager</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>Wang</td>\n",
       "      <td>VP</td>\n",
       "      <td>50000.0</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>Zhang</td>\n",
       "      <td>Manager</td>\n",
       "      <td>NaN</td>\n",
       "      <td>VP</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>Li</td>\n",
       "      <td>NaN</td>\n",
       "      <td>5000.0</td>\n",
       "      <td>Manager</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "    name      job      sal   report\n",
       "0   Wang       VP  50000.0      NaN\n",
       "1  Zhang  Manager      NaN       VP\n",
       "2     Li      NaN   5000.0  Manager\n",
       "3   Wang       VP  50000.0      NaN\n",
       "4  Zhang  Manager      NaN       VP\n",
       "5     Li      NaN   5000.0  Manager\n",
       "6   Wang       VP  50000.0      NaN\n",
       "7  Zhang  Manager      NaN       VP\n",
       "8     Li      NaN   5000.0  Manager"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.concat([data_employee_ri, data_employee_ri, data_employee_ri],ignore_index=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "984942fc",
   "metadata": {},
   "source": [
    "### 3.1.3 纵向拼接：Merge"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d5453247",
   "metadata": {},
   "source": [
    "根据数据列关联，使用on关键字\n",
    "\n",
    "* 可以指定一列或多列\n",
    "* 可以使用left_on和right_on"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "b9fed926",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>name</th>\n",
       "      <th>job_x</th>\n",
       "      <th>sal_x</th>\n",
       "      <th>report_x</th>\n",
       "      <th>job_y</th>\n",
       "      <th>sal_y</th>\n",
       "      <th>report_y</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>Wang</td>\n",
       "      <td>VP</td>\n",
       "      <td>50000.0</td>\n",
       "      <td>NaN</td>\n",
       "      <td>VP</td>\n",
       "      <td>50000.0</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>Zhang</td>\n",
       "      <td>Manager</td>\n",
       "      <td>NaN</td>\n",
       "      <td>VP</td>\n",
       "      <td>Manager</td>\n",
       "      <td>NaN</td>\n",
       "      <td>VP</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>Li</td>\n",
       "      <td>NaN</td>\n",
       "      <td>5000.0</td>\n",
       "      <td>Manager</td>\n",
       "      <td>NaN</td>\n",
       "      <td>5000.0</td>\n",
       "      <td>Manager</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "    name    job_x    sal_x report_x    job_y    sal_y report_y\n",
       "0   Wang       VP  50000.0      NaN       VP  50000.0      NaN\n",
       "1  Zhang  Manager      NaN       VP  Manager      NaN       VP\n",
       "2     Li      NaN   5000.0  Manager      NaN   5000.0  Manager"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.merge(data_employee_ri, data_employee_ri, on='name')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "0bc7b943",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>name</th>\n",
       "      <th>job</th>\n",
       "      <th>sal_x</th>\n",
       "      <th>report_x</th>\n",
       "      <th>sal_y</th>\n",
       "      <th>report_y</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>Wang</td>\n",
       "      <td>VP</td>\n",
       "      <td>50000.0</td>\n",
       "      <td>NaN</td>\n",
       "      <td>50000.0</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>Zhang</td>\n",
       "      <td>Manager</td>\n",
       "      <td>NaN</td>\n",
       "      <td>VP</td>\n",
       "      <td>NaN</td>\n",
       "      <td>VP</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>Li</td>\n",
       "      <td>NaN</td>\n",
       "      <td>5000.0</td>\n",
       "      <td>Manager</td>\n",
       "      <td>5000.0</td>\n",
       "      <td>Manager</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "    name      job    sal_x report_x    sal_y report_y\n",
       "0   Wang       VP  50000.0      NaN  50000.0      NaN\n",
       "1  Zhang  Manager      NaN       VP      NaN       VP\n",
       "2     Li      NaN   5000.0  Manager   5000.0  Manager"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.merge(data_employee_ri, data_employee_ri, on=['name', 'job'])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "064e02c6",
   "metadata": {},
   "source": [
    "根据index关联，可以直接使用left_index和right_index"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "8596c3d1",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>name_x</th>\n",
       "      <th>job_x</th>\n",
       "      <th>sal_x</th>\n",
       "      <th>report_x</th>\n",
       "      <th>name_y</th>\n",
       "      <th>job_y</th>\n",
       "      <th>sal_y</th>\n",
       "      <th>report_y</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>index1</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>Wang</td>\n",
       "      <td>VP</td>\n",
       "      <td>50000.0</td>\n",
       "      <td>NaN</td>\n",
       "      <td>Wang</td>\n",
       "      <td>VP</td>\n",
       "      <td>50000.0</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>Zhang</td>\n",
       "      <td>Manager</td>\n",
       "      <td>NaN</td>\n",
       "      <td>VP</td>\n",
       "      <td>Zhang</td>\n",
       "      <td>Manager</td>\n",
       "      <td>NaN</td>\n",
       "      <td>VP</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>Li</td>\n",
       "      <td>NaN</td>\n",
       "      <td>5000.0</td>\n",
       "      <td>Manager</td>\n",
       "      <td>Li</td>\n",
       "      <td>NaN</td>\n",
       "      <td>5000.0</td>\n",
       "      <td>Manager</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "       name_x    job_x    sal_x report_x name_y    job_y    sal_y report_y\n",
       "index1                                                                    \n",
       "0        Wang       VP  50000.0      NaN   Wang       VP  50000.0      NaN\n",
       "1       Zhang  Manager      NaN       VP  Zhang  Manager      NaN       VP\n",
       "2          Li      NaN   5000.0  Manager     Li      NaN   5000.0  Manager"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data_employee_ri.index.name = 'index1'\n",
    "pd.merge(data_employee_ri, data_employee_ri, left_index=True, right_index=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "986acea7",
   "metadata": {},
   "source": [
    "TIPS: 增加how关键字，并指定\n",
    "* how = 'inner'\n",
    "* how = 'left'\n",
    "* how = 'right'\n",
    "* how = 'outer'\n",
    "\n",
    "结合how，可以看到merge基本再现了SQL应有的功能，并保持代码整洁。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "ceeb1b3c",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>name</th>\n",
       "      <th>sal</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>老王</td>\n",
       "      <td>5000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>老张</td>\n",
       "      <td>3000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>老李</td>\n",
       "      <td>1000</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "  name   sal\n",
       "0   老王  5000\n",
       "1   老张  3000\n",
       "2   老李  1000"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df31_a = pd.DataFrame({'name':['老王', '老张', '老李'], 'sal':[5000, 3000, 1000]})\n",
    "df31_a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "79d624b2",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>name</th>\n",
       "      <th>job</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>老王</td>\n",
       "      <td>VP</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>老刘</td>\n",
       "      <td>Manager</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "  name      job\n",
       "0   老王       VP\n",
       "1   老刘  Manager"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df31_b = pd.DataFrame({'name':['老王', '老刘'], 'job':['VP', 'Manager']})\n",
    "df31_b"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f216187f",
   "metadata": {},
   "source": [
    "how='left': 保留左表信息"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "6fa59bc5",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>name</th>\n",
       "      <th>sal</th>\n",
       "      <th>job</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>老王</td>\n",
       "      <td>5000</td>\n",
       "      <td>VP</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>老张</td>\n",
       "      <td>3000</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>老李</td>\n",
       "      <td>1000</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "  name   sal  job\n",
       "0   老王  5000   VP\n",
       "1   老张  3000  NaN\n",
       "2   老李  1000  NaN"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.merge(df31_a, df31_b, on='name', how='left')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "02a94c40",
   "metadata": {},
   "source": [
    "how='right': 保留右表信息"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "27c59de7",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>name</th>\n",
       "      <th>sal</th>\n",
       "      <th>job</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>老王</td>\n",
       "      <td>5000.0</td>\n",
       "      <td>VP</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>老刘</td>\n",
       "      <td>NaN</td>\n",
       "      <td>Manager</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "  name     sal      job\n",
       "0   老王  5000.0       VP\n",
       "1   老刘     NaN  Manager"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.merge(df31_a, df31_b, on='name', how='right')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "812279f0",
   "metadata": {},
   "source": [
    "how='inner': 保留两表交集信息，这样尽量避免出现缺失值"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "49acad1a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>name</th>\n",
       "      <th>sal</th>\n",
       "      <th>job</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>老王</td>\n",
       "      <td>5000</td>\n",
       "      <td>VP</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "  name   sal job\n",
       "0   老王  5000  VP"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.merge(df31_a, df31_b, on='name', how='inner')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "19ab2580",
   "metadata": {},
   "source": [
    "how='outer': 保留两表并集信息，这样会导致缺失值，但最大程度的整合了已有信息"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "7be29526",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>name</th>\n",
       "      <th>sal</th>\n",
       "      <th>job</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>老王</td>\n",
       "      <td>5000.0</td>\n",
       "      <td>VP</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>老张</td>\n",
       "      <td>3000.0</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>老李</td>\n",
       "      <td>1000.0</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>老刘</td>\n",
       "      <td>NaN</td>\n",
       "      <td>Manager</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "  name     sal      job\n",
       "0   老王  5000.0       VP\n",
       "1   老张  3000.0      NaN\n",
       "2   老李  1000.0      NaN\n",
       "3   老刘     NaN  Manager"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.merge(df31_a, df31_b, on='name', how='outer')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9b062ab5",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "### 3.2 数据清洗三剑客\n",
    "\n",
    "接下来的三个功能，**map**,**applymap**,**apply**,功能，是绝大多数数据分析师在数据清洗这一步骤中的必经之路。\n",
    "\n",
    "他们分别回答了以下问题：\n",
    "\n",
    "* 我想根据一列数据新做一列数据，怎么办？（Series->Series）\n",
    "* 我想根据整张表的数据新做整张表，怎么办？ （DataFrame->DataFrame）\n",
    "* 我想根据很多列的数据新做一列数据，怎么办？ （DataFrame->Series）\n",
    "\n",
    "不要再写什么for循环了！改变思维，提高编码和执行效率"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "6d200af3",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>nation</th>\n",
       "      <th>capital</th>\n",
       "      <th>GDP</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>Japan</td>\n",
       "      <td>Tokyo</td>\n",
       "      <td>4000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>Korea</td>\n",
       "      <td>Seoul</td>\n",
       "      <td>1300</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>China</td>\n",
       "      <td>Beijing</td>\n",
       "      <td>9100</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "  nation  capital   GDP\n",
       "0  Japan    Tokyo  4000\n",
       "1  Korea    Seoul  1300\n",
       "2  China  Beijing  9100"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data_np = np.asarray([('Japan', 'Tokyo', 4000),\n",
    "                      ('Korea', 'Seoul', 1300),\n",
    "                      ('China', 'Beijing', 9100)])\n",
    "df32 = pd.DataFrame(data_np, columns=['nation', 'capital', 'GDP'])\n",
    "df32"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c5f2d88c",
   "metadata": {},
   "source": [
    "### map: 以相同规则将一列数据作一个映射，也就是进行相同函数的处理"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "70059446",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>nation</th>\n",
       "      <th>capital</th>\n",
       "      <th>GDP</th>\n",
       "      <th>GDP_Level</th>\n",
       "      <th>NATION</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>Japan</td>\n",
       "      <td>Tokyo</td>\n",
       "      <td>4000</td>\n",
       "      <td>Medium</td>\n",
       "      <td>JAPAN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>Korea</td>\n",
       "      <td>Seoul</td>\n",
       "      <td>1300</td>\n",
       "      <td>Low</td>\n",
       "      <td>KOREA</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>China</td>\n",
       "      <td>Beijing</td>\n",
       "      <td>9100</td>\n",
       "      <td>High</td>\n",
       "      <td>CHINA</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "  nation  capital   GDP GDP_Level NATION\n",
       "0  Japan    Tokyo  4000    Medium  JAPAN\n",
       "1  Korea    Seoul  1300       Low  KOREA\n",
       "2  China  Beijing  9100      High  CHINA"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def GDP_Factorize(v):\n",
    "    fv = np.float64(v)\n",
    "    if fv > 6000.0:\n",
    "        return 'High'\n",
    "    elif fv < 2000.0:\n",
    "        return 'Low'\n",
    "    else:\n",
    "        return 'Medium'\n",
    "\n",
    "df32['GDP_Level'] = df32['GDP'].map(GDP_Factorize)\n",
    "df32['NATION'] = df32.nation.map(str.upper)\n",
    "df32"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "dac7e15d",
   "metadata": {},
   "source": [
    "### 类似的功能还有applymap，可以对一个dataframe里面每一个元素像map那样全局操作"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "e2583d2d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>nation</th>\n",
       "      <th>capital</th>\n",
       "      <th>GDP</th>\n",
       "      <th>GDP_Level</th>\n",
       "      <th>NATION</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>JAPAN</td>\n",
       "      <td>TOKYO</td>\n",
       "      <td>8000.0</td>\n",
       "      <td>MEDIUM</td>\n",
       "      <td>JAPAN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>KOREA</td>\n",
       "      <td>SEOUL</td>\n",
       "      <td>2600.0</td>\n",
       "      <td>LOW</td>\n",
       "      <td>KOREA</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>CHINA</td>\n",
       "      <td>BEIJING</td>\n",
       "      <td>18200.0</td>\n",
       "      <td>HIGH</td>\n",
       "      <td>CHINA</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "  nation  capital      GDP GDP_Level NATION\n",
       "0  JAPAN    TOKYO   8000.0    MEDIUM  JAPAN\n",
       "1  KOREA    SEOUL   2600.0       LOW  KOREA\n",
       "2  CHINA  BEIJING  18200.0      HIGH  CHINA"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df32.applymap(lambda x: float(x)*2 if x.isdigit() else x.upper())"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e8e72115",
   "metadata": {},
   "source": [
    "### apply则可以对一个DataFrame操作得到一个Series\n",
    "\n",
    "他会有点像我们后面介绍的agg,但是apply可以按行操作和按列操作，用axis控制即可。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "cbdaec12",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0      JapanTokyo_4000\n",
       "1      KoreaSeoul_1300\n",
       "2    ChinaBeijing_9100\n",
       "dtype: object"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df32.apply(lambda x: x['nation'] + x['capital'] + '_' + x['GDP'], axis=1)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7e89b6a6",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "### 3.3 数据排序"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8dd02c2e",
   "metadata": {},
   "source": [
    "* sort: 按一列或者多列的值进行行级排序\n",
    "* sort_index: 根据index里的取值进行排序，而且可以根据axis决定是重排行还是列"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "c9fe3718",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>nation</th>\n",
       "      <th>capital</th>\n",
       "      <th>GDP</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>Japan</td>\n",
       "      <td>Tokyo</td>\n",
       "      <td>4000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>Korea</td>\n",
       "      <td>Seoul</td>\n",
       "      <td>1300</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>China</td>\n",
       "      <td>Beijing</td>\n",
       "      <td>9100</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "  nation  capital   GDP\n",
       "0  Japan    Tokyo  4000\n",
       "1  Korea    Seoul  1300\n",
       "2  China  Beijing  9100"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data_np = np.asarray([('Japan', 'Tokyo', 4000),\n",
    "                      ('Korea', 'Seoul', 1300),\n",
    "                      ('China', 'Beijing', 9100)])\n",
    "df33 = pd.DataFrame(data_np, columns=['nation', 'capital', 'GDP'])\n",
    "df33"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "acc84d45",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>nation</th>\n",
       "      <th>capital</th>\n",
       "      <th>GDP</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>China</td>\n",
       "      <td>Beijing</td>\n",
       "      <td>9100</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>Korea</td>\n",
       "      <td>Seoul</td>\n",
       "      <td>1300</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>Japan</td>\n",
       "      <td>Tokyo</td>\n",
       "      <td>4000</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "  nation  capital   GDP\n",
       "2  China  Beijing  9100\n",
       "1  Korea    Seoul  1300\n",
       "0  Japan    Tokyo  4000"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df33.sort_values(['capital', 'nation'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "255d7dea",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>nation</th>\n",
       "      <th>capital</th>\n",
       "      <th>GDP</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>China</td>\n",
       "      <td>Beijing</td>\n",
       "      <td>9100</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>Japan</td>\n",
       "      <td>Tokyo</td>\n",
       "      <td>4000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>Korea</td>\n",
       "      <td>Seoul</td>\n",
       "      <td>1300</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "  nation  capital   GDP\n",
       "2  China  Beijing  9100\n",
       "0  Japan    Tokyo  4000\n",
       "1  Korea    Seoul  1300"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df33.sort_values('GDP', ascending=False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "5b9dd109",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>GDP</th>\n",
       "      <th>capital</th>\n",
       "      <th>nation</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>4000</td>\n",
       "      <td>Tokyo</td>\n",
       "      <td>Japan</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1300</td>\n",
       "      <td>Seoul</td>\n",
       "      <td>Korea</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>9100</td>\n",
       "      <td>Beijing</td>\n",
       "      <td>China</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "    GDP  capital nation\n",
       "0  4000    Tokyo  Japan\n",
       "1  1300    Seoul  Korea\n",
       "2  9100  Beijing  China"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df33.sort_index(axis=1, ascending=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "48b92962",
   "metadata": {},
   "source": [
    "一个好用的功能：Rank"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "b8c72009",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>nation</th>\n",
       "      <th>capital</th>\n",
       "      <th>GDP</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>Japan</td>\n",
       "      <td>Tokyo</td>\n",
       "      <td>4000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>Korea</td>\n",
       "      <td>Seoul</td>\n",
       "      <td>1300</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>China</td>\n",
       "      <td>Beijing</td>\n",
       "      <td>9100</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "  nation  capital   GDP\n",
       "0  Japan    Tokyo  4000\n",
       "1  Korea    Seoul  1300\n",
       "2  China  Beijing  9100"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df33"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "aa448eba",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>nation</th>\n",
       "      <th>capital</th>\n",
       "      <th>GDP</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>2.0</td>\n",
       "      <td>3.0</td>\n",
       "      <td>2.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>3.0</td>\n",
       "      <td>2.0</td>\n",
       "      <td>1.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>1.0</td>\n",
       "      <td>1.0</td>\n",
       "      <td>3.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   nation  capital  GDP\n",
       "0     2.0      3.0  2.0\n",
       "1     3.0      2.0  1.0\n",
       "2     1.0      1.0  3.0"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df33.rank()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "c0115dea",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>nation</th>\n",
       "      <th>capital</th>\n",
       "      <th>GDP</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>2.0</td>\n",
       "      <td>1.0</td>\n",
       "      <td>2.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1.0</td>\n",
       "      <td>2.0</td>\n",
       "      <td>3.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>3.0</td>\n",
       "      <td>3.0</td>\n",
       "      <td>1.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   nation  capital  GDP\n",
       "0     2.0      1.0  2.0\n",
       "1     1.0      2.0  3.0\n",
       "2     3.0      3.0  1.0"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df33.rank(ascending=False)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7f9948d8",
   "metadata": {},
   "source": [
    "注意tied data（相同值）的处理：\n",
    "* method = 'average'\n",
    "* method = 'min'\n",
    "* method = 'max'\n",
    "* method = 'first'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "8d29a194",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>name</th>\n",
       "      <th>sal</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>老王</td>\n",
       "      <td>5000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>老张</td>\n",
       "      <td>3000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>老李</td>\n",
       "      <td>5000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>老刘</td>\n",
       "      <td>9000</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "  name   sal\n",
       "0   老王  5000\n",
       "1   老张  3000\n",
       "2   老李  5000\n",
       "3   老刘  9000"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df33x = pd.DataFrame({'name': ['老王', '老张', '老李', '老刘'],\n",
    "                      'sal': np.array([5000, 3000, 5000, 9000])})\n",
    "df33x"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3ff95629",
   "metadata": {},
   "source": [
    "df33x.rank()默认使用method='average'，两条数据相等时，处理排名时大家都用平均值"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "e27cfb2e",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0    2.5\n",
       "1    1.0\n",
       "2    2.5\n",
       "3    4.0\n",
       "Name: sal, dtype: float64"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df33x.sal.rank()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f9a419b7",
   "metadata": {},
   "source": [
    "method='min'，处理排名时大家都用最小值"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "0cdbd98e",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0    2.0\n",
       "1    1.0\n",
       "2    2.0\n",
       "3    4.0\n",
       "Name: sal, dtype: float64"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df33x.sal.rank(method='min')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "79e9bd27",
   "metadata": {},
   "source": [
    "method='max'，处理排名时大家都用最大值"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "id": "a7831ac4",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0    3.0\n",
       "1    1.0\n",
       "2    3.0\n",
       "3    4.0\n",
       "Name: sal, dtype: float64"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df33x.sal.rank(method='max')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "eca3f128",
   "metadata": {},
   "source": [
    "method='first'，处理排名时谁先出现就先给谁较小的数值。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "id": "287dc32e",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0    2.0\n",
       "1    1.0\n",
       "2    3.0\n",
       "3    4.0\n",
       "Name: sal, dtype: float64"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df33x.sal.rank(method='first')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d88b6091",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "### 3.4 缺失数据处理"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "id": "625681ad",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Col_1</th>\n",
       "      <th>Col_2</th>\n",
       "      <th>Col_3</th>\n",
       "      <th>Col_4</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>Row_1</th>\n",
       "      <td>0.0</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Row_2</th>\n",
       "      <td>1.0</td>\n",
       "      <td>2.0</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Row_3</th>\n",
       "      <td>3.0</td>\n",
       "      <td>4.0</td>\n",
       "      <td>5.0</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Row_4</th>\n",
       "      <td>6.0</td>\n",
       "      <td>7.0</td>\n",
       "      <td>8.0</td>\n",
       "      <td>9.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "       Col_1  Col_2  Col_3  Col_4\n",
       "Row_1    0.0    NaN    NaN    NaN\n",
       "Row_2    1.0    2.0    NaN    NaN\n",
       "Row_3    3.0    4.0    5.0    NaN\n",
       "Row_4    6.0    7.0    8.0    9.0"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "i = pd.Index([('Row_' + str(x), 'Col_' + str(y + 1)) for x in range(5) for y in range(x)])\n",
    "data_multi = pd.Series(np.arange(10), index=i)\n",
    "df34 = data_multi.unstack()\n",
    "df34"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "301fdacc",
   "metadata": {},
   "source": [
    "忽略缺失值："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "id": "8d5111de",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Col_1    2.500000\n",
       "Col_2    4.333333\n",
       "Col_3    6.500000\n",
       "Col_4    9.000000\n",
       "dtype: float64"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df34.mean(skipna=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "id": "dd2d7e85",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Col_1    2.5\n",
       "Col_2    NaN\n",
       "Col_3    NaN\n",
       "Col_4    NaN\n",
       "dtype: float64"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df34.mean(skipna=False)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "27cd4ac2",
   "metadata": {},
   "source": [
    "如果不想忽略缺失值的话，就需要祭出fillna了："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "id": "4cf36140",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Col_1</th>\n",
       "      <th>Col_2</th>\n",
       "      <th>Col_3</th>\n",
       "      <th>Col_4</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>Row_1</th>\n",
       "      <td>0.0</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Row_2</th>\n",
       "      <td>1.0</td>\n",
       "      <td>2.0</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Row_3</th>\n",
       "      <td>3.0</td>\n",
       "      <td>4.0</td>\n",
       "      <td>5.0</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Row_4</th>\n",
       "      <td>6.0</td>\n",
       "      <td>7.0</td>\n",
       "      <td>8.0</td>\n",
       "      <td>9.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "       Col_1  Col_2  Col_3  Col_4\n",
       "Row_1    0.0    NaN    NaN    NaN\n",
       "Row_2    1.0    2.0    NaN    NaN\n",
       "Row_3    3.0    4.0    5.0    NaN\n",
       "Row_4    6.0    7.0    8.0    9.0"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df34"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "id": "69f06f6d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Row_1    0.00\n",
       "Row_2    0.75\n",
       "Row_3    3.00\n",
       "Row_4    7.50\n",
       "dtype: float64"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df34.fillna(0).mean(axis=1, skipna=False)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "91996d30",
   "metadata": {},
   "source": [
    "# 4. “一组”大熊猫：Pandas的groupby"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d2f0a384",
   "metadata": {},
   "source": [
    "groupby的功能类似SQL的group by关键字：\n",
    "\n",
    "Split-Apply-Combine\n",
    "\n",
    "* Split，就是按照规则分组\n",
    "* Apply，通过一定的agg函数来获得输入pd.Series返回一个值的效果\n",
    "* Combine，把结果收集起来\n",
    "\n",
    "Pandas的groupby的灵活性：\n",
    "\n",
    "* 分组的关键字可以来自于index，也可以来自于真实的列数据\n",
    "* 分组规则可以通过一列或者多列"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2295da13",
   "metadata": {},
   "source": [
    "分组的具体逻辑"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "id": "f7aa2d0a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>sepal_length</th>\n",
       "      <th>sepal_width</th>\n",
       "      <th>petal_length</th>\n",
       "      <th>petal_width</th>\n",
       "      <th>class</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>5.1</td>\n",
       "      <td>3.5</td>\n",
       "      <td>1.4</td>\n",
       "      <td>0.2</td>\n",
       "      <td>Iris-setosa</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>4.9</td>\n",
       "      <td>3.0</td>\n",
       "      <td>1.4</td>\n",
       "      <td>0.2</td>\n",
       "      <td>Iris-setosa</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>4.7</td>\n",
       "      <td>3.2</td>\n",
       "      <td>1.3</td>\n",
       "      <td>0.2</td>\n",
       "      <td>Iris-setosa</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>4.6</td>\n",
       "      <td>3.1</td>\n",
       "      <td>1.5</td>\n",
       "      <td>0.2</td>\n",
       "      <td>Iris-setosa</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>5.0</td>\n",
       "      <td>3.6</td>\n",
       "      <td>1.4</td>\n",
       "      <td>0.2</td>\n",
       "      <td>Iris-setosa</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>145</th>\n",
       "      <td>6.7</td>\n",
       "      <td>3.0</td>\n",
       "      <td>5.2</td>\n",
       "      <td>2.3</td>\n",
       "      <td>Iris-virginica</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>146</th>\n",
       "      <td>6.3</td>\n",
       "      <td>2.5</td>\n",
       "      <td>5.0</td>\n",
       "      <td>1.9</td>\n",
       "      <td>Iris-virginica</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>147</th>\n",
       "      <td>6.5</td>\n",
       "      <td>3.0</td>\n",
       "      <td>5.2</td>\n",
       "      <td>2.0</td>\n",
       "      <td>Iris-virginica</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>148</th>\n",
       "      <td>6.2</td>\n",
       "      <td>3.4</td>\n",
       "      <td>5.4</td>\n",
       "      <td>2.3</td>\n",
       "      <td>Iris-virginica</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>149</th>\n",
       "      <td>5.9</td>\n",
       "      <td>3.0</td>\n",
       "      <td>5.1</td>\n",
       "      <td>1.8</td>\n",
       "      <td>Iris-virginica</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>150 rows × 5 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "     sepal_length  sepal_width  petal_length  petal_width           class\n",
       "0             5.1          3.5           1.4          0.2     Iris-setosa\n",
       "1             4.9          3.0           1.4          0.2     Iris-setosa\n",
       "2             4.7          3.2           1.3          0.2     Iris-setosa\n",
       "3             4.6          3.1           1.5          0.2     Iris-setosa\n",
       "4             5.0          3.6           1.4          0.2     Iris-setosa\n",
       "..            ...          ...           ...          ...             ...\n",
       "145           6.7          3.0           5.2          2.3  Iris-virginica\n",
       "146           6.3          2.5           5.0          1.9  Iris-virginica\n",
       "147           6.5          3.0           5.2          2.0  Iris-virginica\n",
       "148           6.2          3.4           5.4          2.3  Iris-virginica\n",
       "149           5.9          3.0           5.1          1.8  Iris-virginica\n",
       "\n",
       "[150 rows x 5 columns]"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "iris_file = '../data/numpy/iris.data.txt'\n",
    "cnames = ['sepal_length', 'sepal_width', 'petal_length', 'petal_width', 'class']\n",
    "\n",
    "irisdata = pd.read_csv(iris_file, names=cnames, encoding='utf-8')\n",
    "irisdata"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "id": "fa7f7838",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<pandas.core.groupby.generic.DataFrameGroupBy object at 0x7ff6ca74e7f0>"
      ]
     },
     "execution_count": 35,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "irisdata_group = irisdata.groupby('class')\n",
    "irisdata_group"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "id": "fdfe71a9",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Iris-setosa\n",
      "    sepal_length  sepal_width  petal_length  petal_width        class\n",
      "0            5.1          3.5           1.4          0.2  Iris-setosa\n",
      "20           5.4          3.4           1.7          0.2  Iris-setosa\n",
      "40           5.0          3.5           1.3          0.3  Iris-setosa\n",
      "Iris-versicolor\n",
      "    sepal_length  sepal_width  petal_length  petal_width            class\n",
      "50           7.0          3.2           4.7          1.4  Iris-versicolor\n",
      "70           5.9          3.2           4.8          1.8  Iris-versicolor\n",
      "90           5.5          2.6           4.4          1.2  Iris-versicolor\n",
      "Iris-virginica\n",
      "     sepal_length  sepal_width  petal_length  petal_width           class\n",
      "100           6.3          3.3           6.0          2.5  Iris-virginica\n",
      "120           6.9          3.2           5.7          2.3  Iris-virginica\n",
      "140           6.7          3.1           5.6          2.4  Iris-virginica\n"
     ]
    }
   ],
   "source": [
    "for level, subsetDF in irisdata_group:\n",
    "    print(level)\n",
    "    print(subsetDF[::20])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "55df6b15",
   "metadata": {},
   "source": [
    "分组可以快速实现MapReduce的逻辑\n",
    "\n",
    "* Map: 指定分组的列标签，不同的值就会被扔到不同的分组处理\n",
    "* Reduce: 输入多个值，返回一个值，一般可以通过agg实现，agg能接受一个函数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "id": "4b032675",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>sepal_length</th>\n",
       "      <th>sepal_width</th>\n",
       "      <th>petal_length</th>\n",
       "      <th>petal_width</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>class</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>Iris-setosa</th>\n",
       "      <td>0.116502</td>\n",
       "      <td>0.103857</td>\n",
       "      <td>0.069702</td>\n",
       "      <td>1.161506</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Iris-versicolor</th>\n",
       "      <td>0.102232</td>\n",
       "      <td>-0.352014</td>\n",
       "      <td>-0.588404</td>\n",
       "      <td>-0.030249</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Iris-virginica</th>\n",
       "      <td>0.114492</td>\n",
       "      <td>0.355026</td>\n",
       "      <td>0.533044</td>\n",
       "      <td>-0.125612</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                 sepal_length  sepal_width  petal_length  petal_width\n",
       "class                                                                \n",
       "Iris-setosa          0.116502     0.103857      0.069702     1.161506\n",
       "Iris-versicolor      0.102232    -0.352014     -0.588404    -0.030249\n",
       "Iris-virginica       0.114492     0.355026      0.533044    -0.125612"
      ]
     },
     "execution_count": 37,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "irisdata.groupby('class').agg(lambda x:((x - x.mean())**3).sum() * (len(x) - 0.0) / \n",
    "                (len(x) - 1.0) / (len(x) - 2.0) / (x.std() * np.sqrt((len(x) - 0.0) / \n",
    "                                                                     (len(x)-1.0)))**3 if len(x) > 2 else None)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "id": "bada1d30",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>sepal_length</th>\n",
       "      <th>sepal_width</th>\n",
       "      <th>petal_length</th>\n",
       "      <th>petal_width</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>class</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>Iris-setosa</th>\n",
       "      <td>0.116454</td>\n",
       "      <td>0.103814</td>\n",
       "      <td>0.069673</td>\n",
       "      <td>1.161022</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Iris-versicolor</th>\n",
       "      <td>0.102190</td>\n",
       "      <td>-0.351867</td>\n",
       "      <td>-0.588159</td>\n",
       "      <td>-0.030236</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Iris-virginica</th>\n",
       "      <td>0.114445</td>\n",
       "      <td>0.354878</td>\n",
       "      <td>0.532822</td>\n",
       "      <td>-0.125560</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                 sepal_length  sepal_width  petal_length  petal_width\n",
       "class                                                                \n",
       "Iris-setosa          0.116454     0.103814      0.069673     1.161022\n",
       "Iris-versicolor      0.102190    -0.351867     -0.588159    -0.030236\n",
       "Iris-virginica       0.114445     0.354878      0.532822    -0.125560"
      ]
     },
     "execution_count": 38,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import scipy.stats\n",
    "irisdata.groupby('class').agg(scipy.stats.skew)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f8573c84",
   "metadata": {},
   "source": [
    "#### 汇总之后的广播操作\n",
    "\n",
    "在OLAP数据库上，为了避免groupby+join的二次操作，提出了sum()over(partition by)的开窗操作。\n",
    "\n",
    "在Pandas中，这种操作能够进一步被transform所取代。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "id": "a6a0e806",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>sepal_length</th>\n",
       "      <th>sepal_width</th>\n",
       "      <th>petal_length</th>\n",
       "      <th>petal_width</th>\n",
       "      <th>class</th>\n",
       "      <th>sepal_length</th>\n",
       "      <th>sepal_width</th>\n",
       "      <th>petal_length</th>\n",
       "      <th>petal_width</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>5.1</td>\n",
       "      <td>3.5</td>\n",
       "      <td>1.4</td>\n",
       "      <td>0.2</td>\n",
       "      <td>Iris-setosa</td>\n",
       "      <td>5.006</td>\n",
       "      <td>3.418</td>\n",
       "      <td>1.464</td>\n",
       "      <td>0.244</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>20</th>\n",
       "      <td>5.4</td>\n",
       "      <td>3.4</td>\n",
       "      <td>1.7</td>\n",
       "      <td>0.2</td>\n",
       "      <td>Iris-setosa</td>\n",
       "      <td>5.006</td>\n",
       "      <td>3.418</td>\n",
       "      <td>1.464</td>\n",
       "      <td>0.244</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>40</th>\n",
       "      <td>5.0</td>\n",
       "      <td>3.5</td>\n",
       "      <td>1.3</td>\n",
       "      <td>0.3</td>\n",
       "      <td>Iris-setosa</td>\n",
       "      <td>5.006</td>\n",
       "      <td>3.418</td>\n",
       "      <td>1.464</td>\n",
       "      <td>0.244</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>60</th>\n",
       "      <td>5.0</td>\n",
       "      <td>2.0</td>\n",
       "      <td>3.5</td>\n",
       "      <td>1.0</td>\n",
       "      <td>Iris-versicolor</td>\n",
       "      <td>5.936</td>\n",
       "      <td>2.770</td>\n",
       "      <td>4.260</td>\n",
       "      <td>1.326</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>80</th>\n",
       "      <td>5.5</td>\n",
       "      <td>2.4</td>\n",
       "      <td>3.8</td>\n",
       "      <td>1.1</td>\n",
       "      <td>Iris-versicolor</td>\n",
       "      <td>5.936</td>\n",
       "      <td>2.770</td>\n",
       "      <td>4.260</td>\n",
       "      <td>1.326</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>100</th>\n",
       "      <td>6.3</td>\n",
       "      <td>3.3</td>\n",
       "      <td>6.0</td>\n",
       "      <td>2.5</td>\n",
       "      <td>Iris-virginica</td>\n",
       "      <td>6.588</td>\n",
       "      <td>2.974</td>\n",
       "      <td>5.552</td>\n",
       "      <td>2.026</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>120</th>\n",
       "      <td>6.9</td>\n",
       "      <td>3.2</td>\n",
       "      <td>5.7</td>\n",
       "      <td>2.3</td>\n",
       "      <td>Iris-virginica</td>\n",
       "      <td>6.588</td>\n",
       "      <td>2.974</td>\n",
       "      <td>5.552</td>\n",
       "      <td>2.026</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>140</th>\n",
       "      <td>6.7</td>\n",
       "      <td>3.1</td>\n",
       "      <td>5.6</td>\n",
       "      <td>2.4</td>\n",
       "      <td>Iris-virginica</td>\n",
       "      <td>6.588</td>\n",
       "      <td>2.974</td>\n",
       "      <td>5.552</td>\n",
       "      <td>2.026</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "     sepal_length  sepal_width  petal_length  petal_width            class  \\\n",
       "0             5.1          3.5           1.4          0.2      Iris-setosa   \n",
       "20            5.4          3.4           1.7          0.2      Iris-setosa   \n",
       "40            5.0          3.5           1.3          0.3      Iris-setosa   \n",
       "60            5.0          2.0           3.5          1.0  Iris-versicolor   \n",
       "80            5.5          2.4           3.8          1.1  Iris-versicolor   \n",
       "100           6.3          3.3           6.0          2.5   Iris-virginica   \n",
       "120           6.9          3.2           5.7          2.3   Iris-virginica   \n",
       "140           6.7          3.1           5.6          2.4   Iris-virginica   \n",
       "\n",
       "     sepal_length  sepal_width  petal_length  petal_width  \n",
       "0           5.006        3.418         1.464        0.244  \n",
       "20          5.006        3.418         1.464        0.244  \n",
       "40          5.006        3.418         1.464        0.244  \n",
       "60          5.936        2.770         4.260        1.326  \n",
       "80          5.936        2.770         4.260        1.326  \n",
       "100         6.588        2.974         5.552        2.026  \n",
       "120         6.588        2.974         5.552        2.026  \n",
       "140         6.588        2.974         5.552        2.026  "
      ]
     },
     "execution_count": 39,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.concat([irisdata, irisdata.groupby('class').transform('mean')], axis=1)[::20]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "64afce79",
   "metadata": {},
   "source": [
    "#### 产生 MultiIndex（多列分组）后的数据透视表操作\n",
    "\n",
    "一般来说，多列groupby的一个副作用就是.groupby().agg()之后你的行index已经变成了一个多列分组的分级索引。\n",
    "\n",
    "如果我们希望达到Excel的数据透视表的效果，行和列的索引自由交换，达到统计目的，究竟应该怎么办呢？"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "id": "19dd8adc",
   "metadata": {},
   "outputs": [],
   "source": [
    "factor1 = np.random.randint(0, 3, 50)\n",
    "factor2 = np.random.randint(0, 2, 50)\n",
    "factor3 = np.random.randint(0, 3, 50)\n",
    "values = np.random.randn(50)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "id": "7053f285",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>F1</th>\n",
       "      <th>F2</th>\n",
       "      <th>F3</th>\n",
       "      <th>F4</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>45</th>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>2</td>\n",
       "      <td>0.183978</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>46</th>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>2</td>\n",
       "      <td>1.251493</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>47</th>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>-0.424046</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>48</th>\n",
       "      <td>2</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>-1.276174</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>49</th>\n",
       "      <td>2</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>-1.239284</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "    F1  F2  F3        F4\n",
       "45   1   1   2  0.183978\n",
       "46   0   0   2  1.251493\n",
       "47   0   0   1 -0.424046\n",
       "48   2   0   0 -1.276174\n",
       "49   2   1   0 -1.239284"
      ]
     },
     "execution_count": 49,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "hierindexDF = pd.DataFrame({'F1': factor1, 'F2': factor2, 'F3': factor3, 'F4': values})\n",
    "hierindexDF.tail()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "id": "91f6fdaf",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th>F4</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>F1</th>\n",
       "      <th>F2</th>\n",
       "      <th>F3</th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th rowspan=\"6\" valign=\"top\">0</th>\n",
       "      <th rowspan=\"3\" valign=\"top\">0</th>\n",
       "      <th>0</th>\n",
       "      <td>2.074013</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1.849194</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>1.998952</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"3\" valign=\"top\">1</th>\n",
       "      <th>0</th>\n",
       "      <td>0.159661</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>-1.349574</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>-0.687127</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"6\" valign=\"top\">1</th>\n",
       "      <th rowspan=\"3\" valign=\"top\">0</th>\n",
       "      <th>0</th>\n",
       "      <td>0.049578</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>-1.997105</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>-0.818087</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"3\" valign=\"top\">1</th>\n",
       "      <th>0</th>\n",
       "      <td>0.768738</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2.950726</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>-0.846996</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"5\" valign=\"top\">2</th>\n",
       "      <th rowspan=\"2\" valign=\"top\">0</th>\n",
       "      <th>0</th>\n",
       "      <td>-0.952434</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>-2.751583</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"3\" valign=\"top\">1</th>\n",
       "      <th>0</th>\n",
       "      <td>1.744497</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>0.923548</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>1.856369</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                F4\n",
       "F1 F2 F3          \n",
       "0  0  0   2.074013\n",
       "      1   1.849194\n",
       "      2   1.998952\n",
       "   1  0   0.159661\n",
       "      1  -1.349574\n",
       "      2  -0.687127\n",
       "1  0  0   0.049578\n",
       "      1  -1.997105\n",
       "      2  -0.818087\n",
       "   1  0   0.768738\n",
       "      1   2.950726\n",
       "      2  -0.846996\n",
       "2  0  0  -0.952434\n",
       "      1  -2.751583\n",
       "   1  0   1.744497\n",
       "      1   0.923548\n",
       "      2   1.856369"
      ]
     },
     "execution_count": 42,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "hierindexDF_gbsum = hierindexDF.groupby(['F1', 'F2', 'F3']).sum()\n",
    "hierindexDF_gbsum"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4ecb005e",
   "metadata": {},
   "source": [
    "观察Index："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "id": "bbe16c8a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "MultiIndex([(0, 0, 0),\n",
       "            (0, 0, 1),\n",
       "            (0, 0, 2),\n",
       "            (0, 1, 0),\n",
       "            (0, 1, 1),\n",
       "            (0, 1, 2),\n",
       "            (1, 0, 0),\n",
       "            (1, 0, 1),\n",
       "            (1, 0, 2),\n",
       "            (1, 1, 0),\n",
       "            (1, 1, 1),\n",
       "            (1, 1, 2),\n",
       "            (2, 0, 0),\n",
       "            (2, 0, 1),\n",
       "            (2, 1, 0),\n",
       "            (2, 1, 1),\n",
       "            (2, 1, 2)],\n",
       "           names=['F1', 'F2', 'F3'])"
      ]
     },
     "execution_count": 43,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "hierindexDF_gbsum.index"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "26aecc0d",
   "metadata": {},
   "source": [
    "unstack：\n",
    "\n",
    "* 无参数时，把最末index置换到column上\n",
    "* 有数字参数时，把指定位置的index置换到column上\n",
    "* 有列表参数时，依次把特定位置的index置换到column上"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "id": "dac4ae3b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead tr th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe thead tr:last-of-type th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th colspan=\"3\" halign=\"left\">F4</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th></th>\n",
       "      <th>F3</th>\n",
       "      <th>0</th>\n",
       "      <th>1</th>\n",
       "      <th>2</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>F1</th>\n",
       "      <th>F2</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">0</th>\n",
       "      <th>0</th>\n",
       "      <td>2.074013</td>\n",
       "      <td>1.849194</td>\n",
       "      <td>1.998952</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>0.159661</td>\n",
       "      <td>-1.349574</td>\n",
       "      <td>-0.687127</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">1</th>\n",
       "      <th>0</th>\n",
       "      <td>0.049578</td>\n",
       "      <td>-1.997105</td>\n",
       "      <td>-0.818087</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>0.768738</td>\n",
       "      <td>2.950726</td>\n",
       "      <td>-0.846996</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">2</th>\n",
       "      <th>0</th>\n",
       "      <td>-0.952434</td>\n",
       "      <td>-2.751583</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1.744497</td>\n",
       "      <td>0.923548</td>\n",
       "      <td>1.856369</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "             F4                    \n",
       "F3            0         1         2\n",
       "F1 F2                              \n",
       "0  0   2.074013  1.849194  1.998952\n",
       "   1   0.159661 -1.349574 -0.687127\n",
       "1  0   0.049578 -1.997105 -0.818087\n",
       "   1   0.768738  2.950726 -0.846996\n",
       "2  0  -0.952434 -2.751583       NaN\n",
       "   1   1.744497  0.923548  1.856369"
      ]
     },
     "execution_count": 44,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "hierindexDF_gbsum.unstack()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "id": "fe53ba1e",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead tr th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe thead tr:last-of-type th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th colspan=\"3\" halign=\"left\">F4</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th></th>\n",
       "      <th>F1</th>\n",
       "      <th>0</th>\n",
       "      <th>1</th>\n",
       "      <th>2</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>F2</th>\n",
       "      <th>F3</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th rowspan=\"3\" valign=\"top\">0</th>\n",
       "      <th>0</th>\n",
       "      <td>2.074013</td>\n",
       "      <td>0.049578</td>\n",
       "      <td>-0.952434</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1.849194</td>\n",
       "      <td>-1.997105</td>\n",
       "      <td>-2.751583</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>1.998952</td>\n",
       "      <td>-0.818087</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"3\" valign=\"top\">1</th>\n",
       "      <th>0</th>\n",
       "      <td>0.159661</td>\n",
       "      <td>0.768738</td>\n",
       "      <td>1.744497</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>-1.349574</td>\n",
       "      <td>2.950726</td>\n",
       "      <td>0.923548</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>-0.687127</td>\n",
       "      <td>-0.846996</td>\n",
       "      <td>1.856369</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "             F4                    \n",
       "F1            0         1         2\n",
       "F2 F3                              \n",
       "0  0   2.074013  0.049578 -0.952434\n",
       "   1   1.849194 -1.997105 -2.751583\n",
       "   2   1.998952 -0.818087       NaN\n",
       "1  0   0.159661  0.768738  1.744497\n",
       "   1  -1.349574  2.950726  0.923548\n",
       "   2  -0.687127 -0.846996  1.856369"
      ]
     },
     "execution_count": 45,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "hierindexDF_gbsum.unstack(0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "id": "333c4015",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead tr th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe thead tr:last-of-type th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th colspan=\"2\" halign=\"left\">F4</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th></th>\n",
       "      <th>F2</th>\n",
       "      <th>0</th>\n",
       "      <th>1</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>F1</th>\n",
       "      <th>F3</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th rowspan=\"3\" valign=\"top\">0</th>\n",
       "      <th>0</th>\n",
       "      <td>2.074013</td>\n",
       "      <td>0.159661</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1.849194</td>\n",
       "      <td>-1.349574</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>1.998952</td>\n",
       "      <td>-0.687127</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"3\" valign=\"top\">1</th>\n",
       "      <th>0</th>\n",
       "      <td>0.049578</td>\n",
       "      <td>0.768738</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>-1.997105</td>\n",
       "      <td>2.950726</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>-0.818087</td>\n",
       "      <td>-0.846996</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"3\" valign=\"top\">2</th>\n",
       "      <th>0</th>\n",
       "      <td>-0.952434</td>\n",
       "      <td>1.744497</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>-2.751583</td>\n",
       "      <td>0.923548</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>NaN</td>\n",
       "      <td>1.856369</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "             F4          \n",
       "F2            0         1\n",
       "F1 F3                    \n",
       "0  0   2.074013  0.159661\n",
       "   1   1.849194 -1.349574\n",
       "   2   1.998952 -0.687127\n",
       "1  0   0.049578  0.768738\n",
       "   1  -1.997105  2.950726\n",
       "   2  -0.818087 -0.846996\n",
       "2  0  -0.952434  1.744497\n",
       "   1  -2.751583  0.923548\n",
       "   2        NaN  1.856369"
      ]
     },
     "execution_count": 46,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "hierindexDF_gbsum.unstack(1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "id": "3a6279bc",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead tr th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe thead tr:last-of-type th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr>\n",
       "      <th></th>\n",
       "      <th colspan=\"9\" halign=\"left\">F4</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>F3</th>\n",
       "      <th>0</th>\n",
       "      <th>1</th>\n",
       "      <th>2</th>\n",
       "      <th>0</th>\n",
       "      <th>1</th>\n",
       "      <th>2</th>\n",
       "      <th>0</th>\n",
       "      <th>1</th>\n",
       "      <th>2</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>F1</th>\n",
       "      <th>0</th>\n",
       "      <th>0</th>\n",
       "      <th>0</th>\n",
       "      <th>1</th>\n",
       "      <th>1</th>\n",
       "      <th>1</th>\n",
       "      <th>2</th>\n",
       "      <th>2</th>\n",
       "      <th>2</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>F2</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>2.074013</td>\n",
       "      <td>1.849194</td>\n",
       "      <td>1.998952</td>\n",
       "      <td>0.049578</td>\n",
       "      <td>-1.997105</td>\n",
       "      <td>-0.818087</td>\n",
       "      <td>-0.952434</td>\n",
       "      <td>-2.751583</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>0.159661</td>\n",
       "      <td>-1.349574</td>\n",
       "      <td>-0.687127</td>\n",
       "      <td>0.768738</td>\n",
       "      <td>2.950726</td>\n",
       "      <td>-0.846996</td>\n",
       "      <td>1.744497</td>\n",
       "      <td>0.923548</td>\n",
       "      <td>1.856369</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "          F4                                                              \\\n",
       "F3         0         1         2         0         1         2         0   \n",
       "F1         0         0         0         1         1         1         2   \n",
       "F2                                                                         \n",
       "0   2.074013  1.849194  1.998952  0.049578 -1.997105 -0.818087 -0.952434   \n",
       "1   0.159661 -1.349574 -0.687127  0.768738  2.950726 -0.846996  1.744497   \n",
       "\n",
       "                        \n",
       "F3         1         2  \n",
       "F1         2         2  \n",
       "F2                      \n",
       "0  -2.751583       NaN  \n",
       "1   0.923548  1.856369  "
      ]
     },
     "execution_count": 47,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "hierindexDF_gbsum.unstack([2,0])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5e34909b",
   "metadata": {},
   "source": [
    "更进一步的，stack的功能是和unstack对应，把column上的多级索引换到index上去"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "id": "68bcc192",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th>F4</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>F2</th>\n",
       "      <th>F3</th>\n",
       "      <th>F1</th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th rowspan=\"8\" valign=\"top\">0</th>\n",
       "      <th rowspan=\"3\" valign=\"top\">0</th>\n",
       "      <th>0</th>\n",
       "      <td>2.074013</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>0.049578</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>-0.952434</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"3\" valign=\"top\">1</th>\n",
       "      <th>0</th>\n",
       "      <td>1.849194</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>-1.997105</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>-2.751583</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">2</th>\n",
       "      <th>0</th>\n",
       "      <td>1.998952</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>-0.818087</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"9\" valign=\"top\">1</th>\n",
       "      <th rowspan=\"3\" valign=\"top\">0</th>\n",
       "      <th>0</th>\n",
       "      <td>0.159661</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>0.768738</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>1.744497</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"3\" valign=\"top\">1</th>\n",
       "      <th>0</th>\n",
       "      <td>-1.349574</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2.950726</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>0.923548</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"3\" valign=\"top\">2</th>\n",
       "      <th>0</th>\n",
       "      <td>-0.687127</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>-0.846996</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>1.856369</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                F4\n",
       "F2 F3 F1          \n",
       "0  0  0   2.074013\n",
       "      1   0.049578\n",
       "      2  -0.952434\n",
       "   1  0   1.849194\n",
       "      1  -1.997105\n",
       "      2  -2.751583\n",
       "   2  0   1.998952\n",
       "      1  -0.818087\n",
       "1  0  0   0.159661\n",
       "      1   0.768738\n",
       "      2   1.744497\n",
       "   1  0  -1.349574\n",
       "      1   2.950726\n",
       "      2   0.923548\n",
       "   2  0  -0.687127\n",
       "      1  -0.846996\n",
       "      2   1.856369"
      ]
     },
     "execution_count": 48,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "hierindexDF_gbsum.unstack([2, 0]).stack([1, 2])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3f1e424b",
   "metadata": {},
   "source": [
    "本节完。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "46352415",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}